<?php
/**
 * Created by PhpStorm.
 * User: cyc
 * Date: 2018/1/13
 * Time: 下午5:03
 */

class YoutubeDlCommand extends CComponent
{
    use Shell;
    use util_array;

    const COMMAND_YOUTUBEDL = 'youtube-dl';

    //simulation
    const COMMAND_SIMULATION_OPTION_SKIP_DOWNLOAD = '--skip-download';
    const COMMAND_SIMULATION_OPTION_GET_URL = '-g';
    const COMMAND_SIMULATION_OPTION_GET_TITLE = '-e';
    const COMMAND_SIMULATION_OPTION_GET_ID = '--get-id';
    const COMMAND_SIMULATION_OPTION_GET_THUMBNAIL = '--get-thumbnail';
    const COMMAND_SIMULATION_OPTION_GET_DESCRIPTION = '--get-description';
    const COMMAND_SIMULATION_OPTION_GET_FILENAME = '--get-filename';
    const COMMAND_SIMULATION_OPTION_GET_FORMAT = '--get-format';
    const COMMAND_SIMULATION_OPTION_IGNORE_ERROR = '--i';

    //file
    const COMMAND_FILE_OPTION_BATCH_FILE = '-a';
    const COMMAND_FILE_OPTION_WRITE_INFO_JSON = '--write-info-json';
    const COMMAND_FILE_OPTION_OUTPUT = '-o';

    //Video Selection:
    const COMMAND_VIDEO_OPTION_MAX_FILESIZE = '--max-filesize';
    const COMMAND_VIDEO_OPTION_DOWNLOAD_ARCHIVE = '--download-archive';


    //Video Format Options
    const COMMAND_FORMAT_OPTION_FORMAT = '-f';


    //Thumbnail
    const COMMAND_THUMBNAIL_OPTION_WRITE_THUMBNAIL = '--write-thumbnail';


    public function downLoadVideoInfos($url)
    {
        if (empty($url)) {
            throw  new Exception('url must not be null');
        }
        $command_download_video_infos = [self::COMMAND_YOUTUBEDL, $url, self::COMMAND_SIMULATION_OPTION_SKIP_DOWNLOAD];
        $command_download_video_infos[] = self::COMMAND_FILE_OPTION_WRITE_INFO_JSON;
        $md5Url = md5($url);
        $dir = "data/youtube/$md5Url/";
        if (!is_dir($dir) && !mkdir($dir,0777,true)) {
            throw new Exception('can\'t find this dir ' . $dir);
        }
        $json_out_file = $dir."'%(id)s'";
        $command_download_video_infos[] = self::COMMAND_FILE_OPTION_OUTPUT;
        $command_download_video_infos[] = $json_out_file;
        $command = implode(' ', $command_download_video_infos);
        $result = $this->execCommand($command);
        if ($result['status'] != 0) {
            throw  new Exception('execCommand filed' . $command . $result['out']);
        }

        return $result['status'] == 0;
    }

    public function getVideoInfos($url)
    {
        if (empty($url)) {
            throw  new Exception('url must not be null');
        }
        $infos = [];
        $md5Url = md5($url);
        $dir = "data/youtube/$md5Url/";
        if (!is_dir($dir) && !mkdir($dir,0777,true)) {
            throw new Exception('can\'t find this dir ' . $dir);
        }
        $d = dir($dir);
        while (($file = $d->read()) !== false) {
            if (strpos($file, '.info.json') !== false) {
                $data = json_decode(file_get_contents($dir . $file), true);
                $info['source_url'] = self::util_array_get($data, 'webpage_url', '');
                $info['name'] = self::util_array_get($data, 'fulltitle', '');
                $info['plays'] = self::util_array_get($data, 'view_count', '');
                $info['time'] = self::util_array_get($data, 'duration', 0);
                $info['playlist_index'] = self::util_array_get($data, 'playlist_index', 0);
                $infos[] = $info;
            }

        }
        return $infos;
    }

    public function downLoadVideo(Video $video)
    {
        $error = 0;
        $msg = '';
        $data = [];
        try {
            if (!$video->source_url) {
                throw  new Exception('source_url is empty', 1);
            }
            $md5Url = md5($video->source_url);
            $desPath = Yii::getPathOfAlias('application') . "/../video/$md5Url/";
            $command_download_video = [self::COMMAND_YOUTUBEDL, $video->source_url,];
            //dest file
            $out_file = $desPath . "$md5Url.'%(ext)s'";
            $command_download_video[] = self::COMMAND_FILE_OPTION_OUTPUT;
            $command_download_video[] = $out_file;
            //format
            $format = 'mp4';
            $command_download_video[] = self::COMMAND_FORMAT_OPTION_FORMAT;
            $command_download_video[] = $format;
            //max size 100m
            $command_download_video[] = self::COMMAND_VIDEO_OPTION_MAX_FILESIZE;
            $command_download_video[] = '200m';
            //archive
            $archive = $desPath . 'archive.txt';
            $command_download_video[] = self::COMMAND_VIDEO_OPTION_DOWNLOAD_ARCHIVE;
            $command_download_video[] = $archive;
            //Thumbnail
            if (!$video->avetar || file_exists($desPath."$md5Url".'jpg')) {
                $command_download_video[] = self::COMMAND_THUMBNAIL_OPTION_WRITE_THUMBNAIL;
            }

            $command = implode(' ', $command_download_video);
            $result = $this->execCommand($command);
            if (isset($result['status']) && $result['status'] != 0) {
                throw new Exception(json_encode([$result, $command]), 1);
            }
            $data = ['url' => "/video/$md5Url/" . $md5Url . '.mp4', 'avetar' => "/video/$md5Url/" . $md5Url . '.jpg'];
        } catch (Exception $e) {
            $error = $e->getCode();
            $msg = $e->getMessage();
        }
        return [$error, $msg, $data,];
    }


}